#ifndef AFCORE_COMMON_LOG_LOGCOMMON_
#define AFCORE_COMMON_LOG_LOGCOMMON_

#include <atomic>
#include <exception>
#include <string>

#include <fmt/core.h>
#include <fmt/format.h>
#include <fmt/chrono.h>

#include "define.h"
#include "log_fwd.h"

namespace afcore {

/// @brief  日志
namespace log {

/// @brief  日志几倍
enum ELogLevel : uint8_t {
  kLogLevelTrace = 0,   ///< 追踪
  kLogLevelDebug = 1,   ///< 调试
  kLogLevelInfo = 2,    ///< 信息
  kLogLevelWarn = 3,    ///< 警告
  kLogLevelError = 4,   ///< 错误
  kLogLevelFatal = 5,   ///< 严重
  kLogLevelOff = 6,     ///< 关闭

  kLogLevelEnable,      ///< 可用数量
};

/// @brief  日志级别转换为字符串视图
AFCORE_COMMON_API RStringView& ToStringView(ELogLevel l) noexcept;
/// @brief  日志级别转换为日志缩写c风格字符串
AFCORE_COMMON_API const char* ToShortCStr(ELogLevel l) noexcept;
/// @brief  字符串转日志级别
AFCORE_COMMON_API ELogLevel ToLevelEnum(const std::string& name) noexcept;

/// @brief  源文件定位
struct SSrcLocInfo {
  constexpr SSrcLocInfo() = default;
  constexpr SSrcLocInfo(const char* filename_in, int line_in, const char* funcname_in)
    : filename(filename_in), line(line_in), funcname(funcname_in) {}

  [[nodiscard]] constexpr bool Empty() const noexcept {
      return 0 == line;
  }

  const char* filename {nullptr};    ///< 文件名
  int line {0};                      ///< 行号
  const char* funcname {nullptr};    ///< 函数名
};

/// @brief  格式化模式时间类型
enum class EPatternTimeType {
  kPatternTimeTypeLocal,  ///< 当地时间
  kPatternTimeTypeUtc,    ///< 世界协调时间
};

/// @brief  异步溢出处理策略
enum class EAsyncOverflowPolicy {
  kAsyncOverflowPolicy_Block,            ///< 阻塞 直到消息可以入队
  kAsyncOverflowPolicy_OverrunOldest,    ///< 如果队满就丢弃最老的消息
};

/// @brief  记录器颜色支持模式
enum class EAppenderColorMode {
  kAppenderColorMode_Always,       ///< 一直
  kAppenderColorMode_Automatic,    ///< 自动
  kAppenderColorMode_Never,        ///< 从不
};

/// @brief  日志异常信息
class AFCORE_COMMON_API CLogException
  : public std::exception {
public:
  /// @brief  显示构造函数
  /// @param  msg     异常信息
  explicit CLogException(std::string msg);
  /// @brief  构造函数
  /// @param  [out]   msg     异常信息
  /// @param  last_errno      错误码
  CLogException(const std::string& msg, int last_errno);
  /// @brief  std::exception 接口
  /// @return 异常信息
  [[nodiscard]] const char* what() const noexcept override;
private:
  std::string msg_; ///< 异常信息
};

/// @brief  抛出日志异常信息
/// @param  msg         异常信息
/// @param  last_errno  错误码
void ThrowCLogeException(const std::string& msg, int last_errno);
/// @brief  抛出日志异常信息
/// @param  msg         异常信息
void ThrowCLogeException(std::string msg);

} // !namespace log

} // !namespace afcore

#endif //! AFCORE_COMMON_LOG_LOGCOMMON_
